using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VoxelEngine;
using VoxelEngine.Utils;

namespace VoxelGame.Character
{
	public class CharacterToolTNT : CharacterTool
	{
		[SerializeField]
		private int _radius = 5;

		[SerializeField]
		private ParticleSystem _particleTray;

		[SerializeField]
		private ParticleSystem _particleExplosion;

		[SerializeField]
		private Transform _particleAnchor;

		[SerializeField]
		private AnimationCurve _particleMotionCurve;

		[SerializeField]
		private float _particleSpeed = 20f;

		public override bool CanStartOperation(bool waitHalfAnimDuration = false)
		{
			return !_hasOperationStarted;
		}

		public override void PlayLongPressBeginAnimation()
		{
			_particle.Play();
		}

		public override void StopLongPressBeginAnimation()
		{
			_particle.Stop();
		}

		public override void Play()
		{
			_animation.Stop();
			_animation.Play(_interactAnimation);
		}

		private IEnumerator TrailAnimation(Vector3 targetPosition)
		{
			GameObject trailGO = DynamicObjectPool.Instance.Create(_particleTray.gameObject);
			trailGO.transform.position = _particleAnchor.transform.position;
			Vector3 initialPosition = trailGO.transform.position;
			ParticleSystem particleSystem = trailGO.GetComponent<ParticleSystem>();
			particleSystem.Stop();
			particleSystem.Play();
			float progress = 0f;
			while (progress < 1f)
			{
				yield return null;
				progress += _particleSpeed * Time.deltaTime;
				trailGO.transform.position = Vector3.Lerp(initialPosition, targetPosition, _particleMotionCurve.Evaluate(progress));
			}
			DynamicObjectPool.Instance.ReturnObject(trailGO);
		}

		public override IEnumerator DestroyBlock(VoxelEngine.World world, Block selectedBlock, Action<Dictionary<BlockType, int>> onBlocksDestroyed, byte blockLight = 0)
		{
			Dictionary<BlockType, int> blocksDestroyed = new Dictionary<BlockType, int>();
			_hasOperationStarted = true;
			Play();
			Vector3i centerWorldPos = default(Vector3i);
			centerWorldPos.x = selectedBlock._wx;
			centerWorldPos.y = selectedBlock._wy;
			centerWorldPos.z = selectedBlock._wz;
			Vector3 targetPosition = new Vector3((float)selectedBlock._wx + 0.5f, (float)selectedBlock._wy + 0.5f, (float)selectedBlock._wz + 0.5f);
			yield return StartCoroutine(TrailAnimation(targetPosition));
			DynamicObjectPool.Instance.Create(_particleExplosion.gameObject, targetPosition);
			yield return null;
			bool success = false;
			for (int i = centerWorldPos.x - _radius; i <= centerWorldPos.x + _radius; i++)
			{
				for (int j = centerWorldPos.y - _radius; j <= centerWorldPos.y + _radius; j++)
				{
					for (int k = centerWorldPos.z - _radius; k <= centerWorldPos.z + _radius; k++)
					{
						if (Vector3i.DistanceSquared(centerWorldPos, i, j, k) >= _radius * _radius)
						{
							continue;
						}
						Block block = world[i, j, k];
						if (block == null || !block.IsSolid() || block.Indestructible())
						{
							continue;
						}
						BlockType type = block.Type;
						if (Destroy(world, block))
						{
							if (!blocksDestroyed.ContainsKey(type))
							{
								blocksDestroyed[type] = 1;
							}
							else
							{
								Dictionary<BlockType, int> dictionary;
								BlockType key;
								(dictionary = blocksDestroyed)[key = type] = dictionary[key] + 1;
							}
							success = true;
						}
					}
				}
			}
			if (success)
			{
				ChunkRenderer.UpdateHeightMap(world, centerWorldPos, _radius + 5);
				ChunkRenderer.LightningFloodArea(world, centerWorldPos, _radius + 5);
				onBlocksDestroyed.Fire(blocksDestroyed);
				yield return new WaitForSeconds(0.25f);
			}
			_hasOperationStarted = false;
		}

		private bool Destroy(VoxelEngine.World world, Block block)
		{
			if (block != null && block.IsSolid() && !block.Indestructible())
			{
				block.Destroy(51);
				Vector3i worldPosition = default(Vector3i);
				worldPosition.x = block._wx;
				worldPosition.y = block._wy;
				worldPosition.z = block._wz;
				world.RefreshNeighborChunksIfNeeded(worldPosition);
				return true;
			}
			return false;
		}
	}
}
